// bind apply call
Function.prototype.apply = function (context, ...args) {
    if (Function.prototype == this) {
        return undefined
    }
    let fn = new Symbol();
    context[fn] = this;
    if (Array.isArray(args)) {
        context[fn](args)
    } else {
        context[fn]()
    }
    delete context[fn];
}

Function.prototype.call = function (context, args) {
    if (Function.prototype == this) {
        return undefined
    }
    let fn = new Symbol();
    context[fn] = this;
    context[fn](args);
    delete context[fn];
}

Function.prototype.bind = function (context, ...arg) {
    if (Function.prototype == this) {
        return undefined
    }
    let self = this;
    return function F(...arg2) {
        if (this instanceof F) {
            return new self([...arg, ...arg2])
        } else {
            return self.apply(context, arg.concat(arg2))
        }
    }


}